package co.za.alicrity.exactcover;

import java.util.ArrayList;
import java.util.List;

import co.za.alicrity.exactcover.linkedlist.Iterator;
import co.za.alicrity.exactcover.linkedlist.LinkedList;
import co.za.alicrity.exactcover.linkedlist.LinkedListHelper;

public class ExactCoverSparceMatrix implements LinkedList<ColumnHeader>{
	
	private ColumnHeader first;
	private ColumnHeader last;
	
	private LinkedListHelper<ExactCoverSparceMatrix,ColumnHeader> helper;
	
	private ExactCoverMatrix matrix;
	
	public ExactCoverSparceMatrix(ExactCoverMatrix matrix){
		this.matrix=matrix;
		helper = new LinkedListHelper<ExactCoverSparceMatrix,ColumnHeader>(this);
		
		for (int col = 0; col < matrix.getCols(); col++ ){
			ColumnHeader columnHeader = new ColumnHeader();
			helper.addNode(columnHeader);
			for (int row = 0; row < matrix.getRows(); row++) {
				
				if(matrix.getAt(row, col)){
					
					columnHeader.addNode(new Node(row, col, columnHeader));
				}
			}
		}
		
		for (int row=0; row<matrix.getRows();row++){
			
			Iterator<ColumnHeader> i = helper.getIterator();
			Node prevNode = null;
			while (i.hasNext()){
				ColumnHeader cur = i.getNext();
				if (cur.nodeExistsForRow(row)){
					if (prevNode==null){
						prevNode=cur.getNodeAtRow(row);
					} else {
						Node curNode = cur.getNodeAtRow(row);
						prevNode.setNextColumn(curNode);
						curNode.setPrevColumn(prevNode);
						prevNode=curNode;
					}
				}
			}
			
		}
		
	}

	@Override
	public ColumnHeader getFirst() {
		return first;
	}

	@Override
	public ColumnHeader getLast() {
		return last;
	}

	@Override
	public void setFirst(ColumnHeader node) {
		first=node;
	}

	@Override
	public void setLast(ColumnHeader node) {
		last=node;
	}
	
	public String toString(){
		return helper.getListString();
	}
	
	public ColumnHeader getColumnWithLeastAmount(){
		
		int least = matrix.getRows();
		
		Iterator<ColumnHeader> i = helper.getIterator();
		while(i.hasNext()){
			int rows = i.getNext().getSize();
			if (rows<least){
				least=rows;
			}
		}
		
		i = helper.getIterator();
		while(i.hasNext()){
			ColumnHeader cur = i.getNext();
			if (cur.getSize()==least){
				return cur;
			}
		}
		
		return null;
		
	}

	public Iterator<ColumnHeader> getIterator() {
		return helper.getIterator();
	}

	public ColumnHeader remove(ColumnHeader node) {
		helper.removeNode(node);
		return node;
	}

	public void putBack(ColumnHeader cur) {
		helper.putBack(cur);
	}

	public boolean isEmpty() {
		Iterator<ColumnHeader> i = helper.getIterator();
		while(i.hasNext()){
			if (i.getNext().getSize()>0){
				return false;
			}
		}
		return true;
	}

	public ExactCoverMatrix getExactcoverMatrix() {
		return matrix;
	}

	

}
